Skip to content

Conversation

@arng40
Copy link
Contributor

@arng40 arng40 commented Nov 5, 2025

Remove code duplication found in GEOS_THROW, GEOS_ERROR, GEOS_WARNING and put into a static function in ErrorLogger.
Called while flushErrorMsg().
Move all Exceptions under GeosExceptions.hpp

… link between GEOS_THROW_CTX_IF and LVARRAY_THROW_IF_TEST( EXP, MSG, TYPE )
… in try/catch statements

Problem: Retrieves everything that was thrown, so not just the message.
…y spaces.

The previous condition checked whether an argument was present and whether the option was immediately followed by a value like -test"value", which excluded valid cases like -test "value" et -test     "value".
}
catch( std::exception const & e )
{ // native exceptions management
ErrorLogger::ErrorMsg & errMsg = ErrorLogger::global().currentErrorMsg();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it lacks a lot of information here: at this point, IIRC, GEOS_THOW() has never been called, so the same information must be provided to the error message.

Appart from that, this part is a lot better!

* potencially at various application layers
* Use flushErrorMsg() when the message is fully constructed and you want it to be output
* @return Reference to the current instance for method chaining.
* potencially at various application layers (Typically for exceptions)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Typically for exceptions"
Are there other use-cases?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have now 2 flush methods

Comment on lines 86 to 89
ErrorContext( map< Attribute, std::string > attributes, integer priority ):
m_dataDisplayString( "" ),
m_attributes( attributes ),
m_priority( priority ) {};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

m_dataDisplayString is allowed as empty? Isn't that the source of your issue in the unit test?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is what is needed : ErrorContext( string formattedContext, map< Attribute, std::string > attributes, integer priority ):

Comment on lines 132 to 140
ErrorLogger::global().beginLogger()
.addSignalToMsg( signal )
.setType( ErrorLogger::MsgType::Error )
.addRank( ::geos::logger::internal::g_rank )
.addCallStackInfo( stackHistory )
.addContextInfo(
ErrorContext{ { { ErrorContext::Attribute::Signal, std::to_string( signal ) } }, 1 },
ErrorContext{ { { ErrorContext::Attribute::DetectionLoc, string( "signal handler" ) } }, 0 } )
.flush();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a unit test for signals would be a good thing.

"***** - {}\n",
testErrorLogger.getCurrentExceptionMsg().m_file, line1,
testErrorLogger.getCurrentExceptionMsg().m_cause,
context.toString(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't you switch with the most important context here?

Comment on lines 96 to 97
/// Error message logger for structured error reporting
DiagnosticMsg m_errorMsg;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't that in currentExceptionMsg()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed

Comment on lines 70 to 91
void prepareWhat( std::string const & msg,
std::string const & cause,
char const * file,
int line,
int rank,
string_view stackTrace ) noexcept
{
try
{
std::ostringstream oss;
oss << "***** GEOS Exception\n";
oss << "***** LOCATION: " << file << ":" << line << "\n";
oss << "***** " << cause << "\n";
oss << "***** Rank " << rank << ": "<< msg <<"\n\n";
oss << stackTrace;
m_cachedWhat = oss.str();
} catch( ... )
{
m_cachedWhat = "GEOS Exception (formatting failed)";
}

}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
void prepareWhat( std::string const & msg,
std::string const & cause,
char const * file,
int line,
int rank,
string_view stackTrace ) noexcept
{
try
{
std::ostringstream oss;
oss << "***** GEOS Exception\n";
oss << "***** LOCATION: " << file << ":" << line << "\n";
oss << "***** " << cause << "\n";
oss << "***** Rank " << rank << ": "<< msg <<"\n\n";
oss << stackTrace;
m_cachedWhat = oss.str();
} catch( ... )
{
m_cachedWhat = "GEOS Exception (formatting failed)";
}
}
private:
static thread_local std::ostringstream formattingOSS;
public:
void prepareWhat( ErrorMsg const & msg ) noexcept
{
formattingOSS.str("");
formattingOSS.clear();
ErrorLogger::writeToAscii( msg, formattingOSS );
m_cachedWhat = formattingOSS.bad ? "Exception formatting error!" : formattingOSS.str();
m_errorMsg = msg;
}

.addToMsg( e.what() )
.addRank( ::geos::logger::internal::g_rank )
.addCallStackInfo( LvArray::system::stackTrace( true ) )
.get();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

who get what?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

renamed

Comment on lines 233 to 236
/// The diagnosticMsg being constructed
DiagnosticMsg m_errorMsg;
/// The target diagnosticMsg
DiagnosticMsg * m_targetErrorMsg = nullptr;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// The diagnosticMsg being constructed
DiagnosticMsg m_errorMsg;
/// The target diagnosticMsg
DiagnosticMsg * m_targetErrorMsg = nullptr;
/// The target diagnosticMsg
DiagnosticMsg & m_targetErrorMsg;

Comment on lines 86 to 89
ErrorContext( map< Attribute, std::string > attributes, integer priority ):
m_dataDisplayString( "" ),
m_attributes( attributes ),
m_priority( priority ) {};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is what is needed : ErrorContext( string formattedContext, map< Attribute, std::string > attributes, integer priority ):


/**
* @brief Write all the information retrieved about the error/warning message into the YAML file
* @param errorMsg a constant reference to the error
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not const

Comment on lines 327 to 335
void flushCurrentExceptionMessage();

/**
* @brief Write all the information retrieved about the diagnostic message into the instance
* outputs (stream specified + optional yaml file)
* @param errorMsg a reference to the ErrorMsg to output, and will be re-initialized
* @note Used for warnings and non-exception errors
*/
void flushErrorMsg( DiagnosticMsg & errMsg );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

provide a oss parameter (with a default to std::cout)?

Comment on lines 149 to 150
static DiagnosticMsgBuilder init()
{ return DiagnosticMsgBuilder();}
Copy link
Contributor

@MelReyCG MelReyCG Jan 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  static ErrorMsgBuilder init( ErrorMsg & msg,
                               MsgType msgType,
                               std::string_view msgContent,
                               integer rank,
                               std::string_view msgFile,
                               integer msgLine );

What do you think of this suggestion? ^
Is that too constraining?

(internally, that would call the builder methods)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok for init with parameters but I removed file & line. For the signal we don't have file & line

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci: run CUDA builds Allows to triggers (costly) CUDA jobs ci: run integrated tests Allows to run the integrated tests in GEOS CI type: cleanup / refactor Non-functional change (NFC)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants